﻿using System;

namespace Samurai.Wakizashi.Workflow
{
    public interface IWorkflow<T> where T : class, IWorkflowContext
    {
        /// <summary>
        /// Occurs when the final step in the workflow has completed.
        /// </summary>
        event EventHandler<WorkflowCompletedEventArgs<T>> WorkflowCompleted;

        /// <summary>
        /// Occurs when a step in the workflow fails.
        /// </summary>
        event EventHandler<WorkflowCompletedEventArgs<T>> WorkflowFailed;

        /// <summary>
        /// Gets or sets the context which to pass along the workflow as it executes.
        /// </summary>
        /// <value>The context.</value>
        T Context { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether or not to restart the workflow after the last step completes.
        /// </summary>
        /// <value><c>true</c> if [loop workflow]; otherwise, <c>false</c>.</value>
        bool LoopWorkflow { get; set; }

        /// <summary>
        /// Gets the number of actions registered in the workflow.
        /// </summary>
        /// <value>The count.</value>
        int Count { get; }

        /// <summary>
        /// Clears all registered actions from the workflow.
        /// </summary>
        void Clear();

        /// <summary>
        /// Starts the workflow by executing the first step.
        /// </summary>
        void Start();

        /// <summary>
        /// Places a request to stop the workflow instance at the most convenient point.
        /// </summary>
        void RequestStop();

        /// <summary>
        /// Called when the final step in the workflow has completed.
        /// </summary>
        void OnCompleted(Action<WorkflowCompletedEventArgs<T>> action);

        /// <summary>
        /// Calledwhen a step in the workflow fails.
        /// </summary>
        void OnFailed(Action<WorkflowCompletedEventArgs<T>> action);
    }
}
